package com.huaboot.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huaboot.commont.page.PageResult;
import com.huaboot.framework.log.dto.OperateLogDto;
import com.huaboot.framework.redis.config.RedisCache;
import com.huaboot.framework.redis.utils.RedisKeyConstant;
import com.huaboot.framework.redis.utils.RedisKeyUtil;
import com.huaboot.system.convert.SysLogOperateConvert;
import com.huaboot.system.entity.SysLogOperateEntity;
import com.huaboot.system.mapper.SysLogOperateMapper;
import com.huaboot.system.query.SysLogOperateQuery;
import com.huaboot.system.service.SysLogOperateService;
import com.huaboot.system.vo.SysLogOperateVO;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 操作日志
 *
 */
@Service
@AllArgsConstructor
public class SysLogOperateServiceImpl extends ServiceImpl<SysLogOperateMapper, SysLogOperateEntity> implements SysLogOperateService {

    private final RedisCache redisCache;

    @Override
    public PageResult<SysLogOperateVO> page(SysLogOperateQuery query) {
        PageHelper.startPage(query.currentPage, query.size);
        List<SysLogOperateEntity> sysLogOperateEntityList = list(getWrapper(query));
        PageInfo<SysLogOperateEntity> page = new PageInfo<>(sysLogOperateEntityList);
        return new PageResult<>(SysLogOperateConvert.INSTANCE.convertList(page.getList()), page.getTotal());
    }

    private LambdaQueryWrapper<SysLogOperateEntity> getWrapper(SysLogOperateQuery query) {
        LambdaQueryWrapper<SysLogOperateEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(query.getStatus() != null, SysLogOperateEntity::getStatus, query.getStatus());
        wrapper.like(StrUtil.isNotBlank(query.getRealName()), SysLogOperateEntity::getRealName, query.getRealName());
        wrapper.like(StrUtil.isNotBlank(query.getModule()), SysLogOperateEntity::getModule, query.getModule());
        wrapper.like(StrUtil.isNotBlank(query.getReqUri()), SysLogOperateEntity::getReqUri, query.getReqUri());
        wrapper.orderByDesc(SysLogOperateEntity::getId);
        return wrapper;
    }

    /**
     * 启动项目时，从Redis队列获取操作日志并保存
     */
    @PostConstruct
    public void saveLog() {
        ScheduledExecutorService scheduledService = ThreadUtil.createScheduledExecutor(1);
        // 每隔10秒钟，执行一次
        scheduledService.scheduleWithFixedDelay(() -> {
            try {
                String key = RedisKeyUtil.generateKey(RedisKeyConstant.SYS_LOG);
                // 每次插入10条
                int count = 10;
                for (int i = 0; i < count; i++) {
                    OperateLogDto log = (OperateLogDto) redisCache.rightPop(key);
                    if (log == null) {
                        return;
                    }
                    SysLogOperateEntity entity = BeanUtil.copyProperties(log, SysLogOperateEntity.class);
                    baseMapper.insert(entity);
                }
            } catch (Exception e) {
                log.error("SysLogOperateServiceImpl.saveLog Error：" ,e);
            }
        }, 1, 10, TimeUnit.SECONDS);
    }
}
